package wechat_sdk_go

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/url"
)

type DefaultConfig struct {
	BaseUrl string
	Timeout int
}

type BaseRequest struct {
	DefaultConfig DefaultConfig
	AccessToken   AccessTokenInterface
}

func NewBaseRequest() *BaseRequest {
	return &BaseRequest{
		DefaultConfig{
			"https://api.weixin.qq.com/",
			5,
		},
		nil,
	}
}

func (bq *BaseRequest) Request(url string, method string, option HttpOption) (Response, error) {

	switch method {
	case "GET":
		return bq.Get(url, option)
	default:
		return bq.Post(url, option)
	}

}

type HttpOption struct {
	Json  map[string]interface{}
	Query map[string][]string
}

func (bq *BaseRequest) Get(url string, option HttpOption) (Response, error) {

	uri := bq.DefaultConfig.BaseUrl + GetUrlParam(url, option.Query)
	rep, err := http.Get(uri)
	return Response{rep}, err

}

func GetUrlParam(urlPath string, param map[string][]string) string {

	if 1 > len(param) {
		return urlPath
	}

	c := url.Values(param)

	params := c.Encode()

	return urlPath + "?" + params

}

func (bq *BaseRequest) Post(url string, option HttpOption) (Response, error) {

	jsonStr, _ := json.Marshal(option.Json)

	body := bytes.NewReader(jsonStr)

	url = bq.DefaultConfig.BaseUrl + GetUrlParam(url, option.Query)

	rep, err := http.Post(url, "application/json", body)

	if nil != err {
		return Response{}, err
	}

	return Response{rep}, nil

}

func (bq *BaseRequest) HttpPostJson(url string, option HttpOption) (Response, error) {

	err := bq.addToken(&option)

	if err != nil {
		return Response{}, err
	}

	return bq.Post(url, option)

}

func (bq *BaseRequest) addToken(option *HttpOption) error {

	accessToken := bq.AccessToken

	token, err := accessToken.GetToken()
	tokenKey := accessToken.GetTokenKey()

	if nil != err {
		return err
	}

	if nil == option.Query {
		option.Query = map[string][]string{
			tokenKey: {token.AccessToken},
		}
	} else {
		option.Query[tokenKey] = []string{token.AccessToken}
	}

	return nil

}
